#include <matrix.hpp>
#include <random.hpp>

#include <algorithm>
#include <iostream>

#include <boost/lambda/lambda.hpp>

using namespace boost::lambda;
using namespace std;
using namespace sm;

int main()
{
	const std::size_t n = 3;

	typedef dynamic_matrix<int> dm; 	
	
	dm lhs(n,n), rhs(n,n), ans(n,n);

	int i = 1;
	for_each( lhs.begin(), lhs.end(), _1=var(i)++ );
	for_each( rhs.begin(), rhs.end(), _1=var(i)++ );

	ans = lhs * rhs;

	cout 	<< "\n lhs: \n" << lhs 
			<< "\n rhs: \n" << rhs
			<< "\n lhs * rhs : \n" << ans;

	dm lhs_(n+1,n+1), rhs_(n+1,n+1), ans_(n+1,n+1);

	copy( lhs.col_range_begin(0,n-1), lhs.col_range_end(0,n-1), lhs_.col_range_begin(0,n-1) );
	copy( rhs.col_range_begin(0,n-1), rhs.col_range_end(0,n-1), rhs_.col_range_begin(0,n-1) );

	ans_ = lhs_ * rhs_;

	cout 	<< "\n lhs_: \n" << lhs_ 
			<< "\n rhs_: \n" << rhs_
			<< "\n lhs_ * rhs_ : \n" << ans_;


	
	dm llhs(n+1,n), rrhs(n,n), aans(n+1,n);

	int ii = 1;
	for_each( llhs.begin(), llhs.end(), _1=var(ii)++ );
	for_each( rrhs.begin(), rrhs.end(), _1=var(ii)++ );

	aans = llhs * rrhs;

	cout 	<< "\n llhs: \n" << llhs 
			<< "\n rrhs: \n" << rrhs
			<< "\n llhs * rrhs : \n" << aans;

	dm llhs_(n,n), rrhs_(n,n), aans_(n,n);

	copy( llhs.col_range_begin(0,n-1), llhs.col_range_end(0,n-1), llhs_.col_range_begin(0,n-1) );
	copy( rrhs.col_range_begin(0,n-1), rrhs.col_range_end(0,n-1), rrhs_.col_range_begin(0,n-1) );

	aans_ = llhs_ * rrhs_;

	cout 	<< "\n llhs_: \n" << llhs_ 
			<< "\n rrhs_: \n" << rrhs_
			<< "\n llhs_ * rrhs_ : \n" << aans_;


	dm lllhs(n,n), rrrhs(n,n+3), aaans(n,n+3);

	int iii = 1;
	for_each( lllhs.begin(), lllhs.end(), _1=var(iii)++ );
	for_each( rrrhs.begin(), rrrhs.end(), _1=var(iii)++ );

	aaans = lllhs * rrrhs;

	cout 	<< "\n lllhs: \n" << lllhs 
			<< "\n rrrhs: \n" << rrrhs
			<< "\n lllhs * rrrhs : \n" << aaans;

	dm lllhs_(n,n+1), rrrhs_(n+1,n+3), aaans_(n,n+3);

	copy( lllhs.col_range_begin(0,n-1), lllhs.col_range_end(0,n-1), lllhs_.col_range_begin(0,n-1) );
	copy( rrrhs.col_range_begin(0,n+2), rrrhs.col_range_end(0,n+2), rrrhs_.col_range_begin(0,n+2) );

	aaans_ = lllhs_ * rrrhs_;

	cout 	<< "\n lllhs_: \n" << lllhs_ 
			<< "\n rrrhs_: \n" << rrrhs_
			<< "\n lllhs_ * rrrhs_ : \n" << aaans_;

	dm llllhs(n,n), rrrrhs(n,n), aaaans(n,n);

	int iiii = 1;
	for_each( llllhs.begin(), llllhs.end(), _1=var(iiii)++ );
	for_each( rrrrhs.begin(), rrrrhs.end(), _1=var(iiii)++ );

	aaaans = llllhs * rrrrhs;

	cout 	<< "\n llllhs: \n" << llllhs 
			<< "\n rrrrhs: \n" << rrrrhs
			<< "\n llllhs * rrrrhs : \n" << aaaans;

	dm llllhs_(n,n+1), rrrrhs_(n+1,n), aaaans_(n,n);

	copy( llllhs.col_range_begin(0,n-1), llllhs.col_range_end(0,n-1), llllhs_.col_range_begin(0,n-1) );
	copy( rrrrhs.col_range_begin(0,n-1), rrrrhs.col_range_end(0,n-1), rrrrhs_.col_range_begin(0,n-1) );

	aaaans_ = llllhs_ * rrrrhs_;

	cout 	<< "\n llllhs_: \n" << llllhs_ 
			<< "\n rrrrhs_: \n" << rrrrhs_
			<< "\n llllhs_ * rrrrhs_ : \n" << aaaans_;






	return 0;
}

